const std = @import("std");

///  编译时生成终端协议解析器（Ghostty）
///  背景：终端模拟器要处理几十种控制序列，如 \x1b[31m 变色。
///  传统做法：运行时查表 + 分支，每条序列至少 100 ns。
///  comptime 做法：在编译期把 ANSI 语法图直接编译成“跳转表 + 状态机”，运行时只有 O(1) 查表。
/// 编译期把字符串表编译成完美哈希跳转表
fn Parser(comptime patterns: []const []const u8) type {
    comptime var jump_table: [256]?u8 = .{null} ** 256;
    inline for (patterns, 0..) |pat, idx| {
        jump_table[pat[0]] = idx; // 首字节直接定序
    }
    return struct {
        jump: @TypeOf(jump_table) = jump_table,

        pub fn parse(self: @This(), buf: []const u8) ?u8 {
            if (buf.len == 0) return null;
            return self.jump[buf[0]];
        }
    };
}

pub fn tt0() void {
    const MyParser = Parser(&.{ "\x1b[31m", "\x1b[32m", "\x1b[0m" });
    const p = MyParser{};
    std.debug.print("idx of \\x1b[32m = {?}\n", .{p.parse("\x1b[32m")});
}

/// 编译时“特化”GPU 内核（CubeCL 灵感）
/// 背景：GPU 计算库需要为不同数据类型（f32/f16/i32）生成最优内核。
/// comptime 做法：把“类型”当参数传进去，编译期生成对应内核字节码，运行时直接提交给驱动。
fn Kernel(comptime T: type) type {
    return struct {
        pub fn call(a: []T, b: []T, c: []T) void {
            for (a, b, c) |*pa, pb, *pc| {
                pc.* = pa.* + pb.*; // 会被 LLVM 向量化
            }
        }
    };
}

pub fn tt1() void {
    const f32Kernel = Kernel(f32);
    var a = [_]f32{ 1, 2, 3 };
    var b = [_]f32{ 4, 5, 6 };
    var c = [_]f32{0} ** 3;
    f32Kernel.call(&a, &b, &c);
    std.debug.print("vec add = {any}\n", .{c});
}

///编译时“迁移”配置字段（Ghostty 向后兼容）
/// 背景：配置文件字段改名后，仍需兼容旧版本。
/// comptime 做法：在编译期生成“旧→新”迁移代码，运行时只做一次常量折叠。
const Config = struct {
    blur: bool = false,

    pub const Deprecated = struct {
        @"blur-radius": ?u8 = null,
    };

    pub fn migrate(comptime old: Deprecated) Config {
        return .{ .blur = old.@"blur-radius" != null };
    }
};

pub fn tt2() void {
    const old: Config.Deprecated = .{ .@"blur-radius" = @as(?u8, 5) };
    const cfg: Config = comptime Config.migrate(old);
    std.debug.print("new, cfg.blur = {}\n", .{cfg.blur});
}

// 编译时预生成 FizzBuzz 字节数组（极限性能 Demo）
// 把整份输出提前算好，运行时一次 writeAll 完成，Unix 上 time 测量比手写 printf 快 9 倍
pub fn tt3() !void {
    const full = comptime init: {
        //var counter = std.Io.countingWriter(std.Io.null_writer);
        var counter = std.Io.Writer.Discarding.fullCount(std.Io.null_writer);

        for (1..101) |i| {
            const w = counter.writer();
            if (@mod(i, 15) == 0) w.writeAll("FizzBuzz\n") catch unreachable //
            else if (@mod(i, 3) == 0) w.writeAll("Fizz\n") catch unreachable //
            else if (@mod(i, 5) == 0) w.writeAll("Buzz\n") catch unreachable //
            else w.print("{}\n", .{i}) catch unreachable;
        }
        var buf: [counter.bytes_written]u8 = undefined;
        var stream = std.Io.fixedBufferStream(&buf);
        for (1..101) |i| {
            const w = stream.writer();
            if (@mod(i, 15) == 0) w.writeAll("FizzBuzz\n") catch unreachable //
            else if (@mod(i, 3) == 0) w.writeAll("Fizz\n") catch unreachable //
            else if (@mod(i, 5) == 0) w.writeAll("Buzz\n") catch unreachable //
            else w.print("{}\n", .{i}) catch unreachable;
        }
        break :init buf;
    };
    try std.Io.getStdOut().writeAll(&full);
}
